package CAS;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicMarkableReference;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * @program: javase
 * @description: 解决ABA问题
 * @author: luolidong
 * @create: 2021-06-24 22:51
 * @version: 1.0
 */
public class ABA2 {
    private static final String A = "A";
    private static final String B = "B";
    private static final String C = "C";
    private static AtomicInteger a = new AtomicInteger(1);
    private static AtomicStampedReference<String> reference = new AtomicStampedReference<>(A, 1);

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            if (reference.compareAndSet(A, B, reference.getStamp(), reference.getStamp() + 1)) {
                System.out.println("A-->B");
            }
        });
        Thread thread1 = new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (reference.compareAndSet(B, A, reference.getStamp(), reference.getStamp() + 1)) {
                System.out.println("B-->A");
            }
        });
//        上面两个线程将A->B->A,后面线程不能成功交换
        Thread thread2 = new Thread(() -> {
            try {
                int stamp = reference.getStamp();
                TimeUnit.SECONDS.sleep(2);
                if (reference.compareAndSet(A, C, stamp, reference.getStamp() + 1)) {
                    System.out.println("A-->C");
                }else {
                    System.out.println("A-->C 失败");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });


        thread2.start();
        thread.start();
        thread1.start();

    }
}
